package scheme;
import accessstruct.AccessControlParameter;
import accessstruct.Tool;
import accessstruct.lsss.LSSSLW10Engine;
import accessstruct.parser.ParserUtils;
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Pairing;
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;
import util.AccessPolicyExamples;
import util.ConfigFileName;

import java.util.Base64;
import java.util.Properties;

import static accessstruct.Tool.loadPropFromFile;
public class LWPPMAABETest {
    public static void basicTest() throws Exception {
        int aaNums = 4;
        ConfigFileName config = new ConfigFileName();
        int [][] accessPolicy = ParserUtils.GenerateAccessPolicy(AccessPolicyExamples.access_policy_example_3);
        String[] rhos = ParserUtils.GenerateRhos(AccessPolicyExamples.access_policy_example_3);
        //访问控制参数，主要是这个ACP
        AccessControlParameter ACP = LSSSLW10Engine.generateAccessControl(accessPolicy ,rhos);

        String userID = "Bob";
        String[] userAttList = AccessPolicyExamples.access_policy_example_3_satisfied_1;
        Pairing bp = PairingFactory.getPairing(config.getPairingParametersFileName());//
        LWPPMAABE.setUp(config ,aaNums,userAttList);
        LWPPMAABE.keyGen(config, userID, userAttList, aaNums);
        Element message =PairingFactory.getPairing(config.getPairingParametersFileName()).getGT().newRandomElement().getImmutable();
        LWPPMAABE.Encrypt( config,   userAttList,  userID, aaNums, message,  ACP);
        Element md = LWPPMAABE.Decrypt( config,  userAttList,  userID,  aaNums, accessPolicy, rhos, ACP);

        System.out.println("解密消息:" + md);
        System.out.println("明文消息:" + message);
        if (message.isEqual(md)) {
            System.out.println("成功解密！");
        }else{
            System.out.println("解密失败！");
        }


    }
    public static void basicTest2(int aaNums ,int attNums) throws Exception {

        ConfigFileName config = new ConfigFileName();
        String att[] =  new String[attNums];
        for(int i = 0;i<attNums;i++){
            att[i] = Integer.toString(i);
        }
        String acp = Tool.convertToAcP(att);

        int [][] accessPolicy = ParserUtils.GenerateAccessPolicy(acp);
        String[] rhos = ParserUtils.GenerateRhos(acp);
        //访问控制参数，主要是这个ACP
        AccessControlParameter ACP = LSSSLW10Engine.generateAccessControl(accessPolicy ,rhos);

        String userID = "Bob";
        String[] userAttList = att;
        Pairing bp = PairingFactory.getPairing(config.getPairingParametersFileName());//
        LWPPMAABE.setUp(config ,aaNums,userAttList);
        LWPPMAABE.keyGen(config, userID, userAttList, aaNums);
        Element message =PairingFactory.getPairing(config.getPairingParametersFileName()).getGT().newRandomElement().getImmutable();
        LWPPMAABE.Encrypt( config,   userAttList,  userID, aaNums, message,  ACP);
        Element md = LWPPMAABE.Decrypt( config,  userAttList,  userID,  aaNums, accessPolicy, rhos, ACP);

        System.out.println("解密消息:" + md);
        System.out.println("明文消息:" + message);
        if (message.isEqual(md)) {
            System.out.println("成功解密！");
        }else{
            System.out.println("解密失败！");
        }

    }
    public static void basicTest3(int aaNums ,int attNums) throws Exception {

        //生成发访问策略
        String att[] =  new String[attNums];
        for(int i = 0;i<attNums;i++){
            att[i] = Integer.toString(i);
        }
        String acp = Tool.convertToAcP(att);
        //加载配置信息
        ConfigFileName config = new ConfigFileName();
        //生成访问策略矩阵
        int [][] accessPolicy = ParserUtils.GenerateAccessPolicy(acp);
        String[] rhos = ParserUtils.GenerateRhos(acp);
        //访问控制参数，主要是这个ACP
        AccessControlParameter ACP = LSSSLW10Engine.generateAccessControl(accessPolicy ,rhos);

        String userID = "Bob";
        String[] userAttList = att;
        //开始流程测试
        LWPPMAABE.setUp(config ,aaNums,userAttList);
        LWPPMAABE.keyGen(config, userID, userAttList, aaNums);
        LWPPMAABE.pxKeyGen( config,  userID,  userAttList , aaNums);
        Element message =PairingFactory.getPairing(config.getPairingParametersFileName()).getGT().newRandomElement().getImmutable();
        LWPPMAABE.offlineEncrypt(config, userAttList, userID, aaNums, ACP);
        LWPPMAABE.onlineEncrypt( config,  message, aaNums);
        RSU.outsourseDecrypt( config,  userAttList,  userID,  aaNums, accessPolicy, rhos, ACP,message);
        LWPPMAABE.Pair<Element, Long> res =LWPPMAABE.localDecrypt( config,  userID);
        System.out.println("解密消息:" + res.getKey());
        System.out.println("明文消息:" + message);
        if (message.isEqual(res.getKey())) {
            System.out.println("成功解密！");
        }else{
            System.out.println("解密失败！");
        }

    }

    public static void basicTest4() throws Exception {
        //固定AA数量为5，测试分别管理 5 10 15 20 25 30 35 40 个属性的时间
        for(int i = 1;i<=11;i++){
            System.out.println("*************************************属性数量是 "+(5*i)+" *************************************");
            basicTest3( 1 ,5*i );//多权威外包解密测试
        }
    }
    public static void AASetUp(int aaNums ,int attNums) throws Exception {

        //生成发访问策略
        String att[] =  new String[attNums];
        for(int i = 0;i<attNums;i++){
            att[i] = Integer.toString(i);
        }
        String acp = Tool.convertToAcP(att);
        //加载配置信息
        ConfigFileName config = new ConfigFileName();
        //生成访问策略矩阵
        int [][] accessPolicy = ParserUtils.GenerateAccessPolicy(acp);
        String[] rhos = ParserUtils.GenerateRhos(acp);
        //访问控制参数，主要是这个ACP
        AccessControlParameter ACP = LSSSLW10Engine.generateAccessControl(accessPolicy ,rhos);

        String userID = "Bob";
        String[] userAttList = att;
        //开始流程测试
        AA.setup(config ,aaNums,userAttList);


    }

    public static void main(String[] args) throws Exception {
//        basicTest();//单权威测试
//        basicTest2( 5 ,20 );//多权威测试
        basicTest3( 1 ,4 );//多权威外包解密测试
        basicTest4();
//        for(int i = 5;i<=5*10;i+=5){
//            System.out.println("*************************************属性数量是 "+(i)+" *************************************");
//            AASetUp( 1 ,i );//多权威外包解密测试
//        }
    }


}
